#ifndef _SPLINE_H_
#define _SPLINE_H_

#include "Polygon.h"
#include "Math\mathlib.h"
//#define		DIV_FACTOR	4.0			// a line with min length of DIV_FACTOR pixels


// the cubic curve segment of a spline
// the 4 control points of the cubic Bezier curve is
// P0 = (m_XOrg, m_YOrg)
// P1 = P0 + B/3
// P2 = P0 + A - C/3
// P3 = P0 + A
class CCurve
{
private:
	double  Ax,Ay;
	double  Bx,By;
	double  Cx,Cy;
	int		Ndiv;

	double	m_XOrg, m_YOrg;

public:
	CCurve(double ax,double ay,double bx,double by,double cx,double cy,int ndiv);
	CCurve(double ax,double ay,double bx,double by,double cx,double cy);
	CCurve();

	double	X( double t );
	double	Y( double t );
	void	SetOrg( double x, double y ) { m_XOrg = x; m_YOrg = y; }
	void	Set(double ax,double ay,double bx,double by,double cx,double cy);
	int		NumPoints();
	void	GetPoints(double x, double y, std::vector<CVertex> &points );
	void	GetPointsAdaptively( double x, double y, std::vector<CVertex> &points, double fError );
	void	Draw( CDC *pDC, double x, double y );
	void	DrawInGL(double x, double y, 
					CSize window_size, float fGLViewWidth, float fGLViewHeight, 
					CPseudoColorRGB &PsdC,Vector2 Origin/*=Vector2(0,0)*/,
					bool bDrawCurve/*=true*/, bool bDrawVertex/*=true*/);
};


// a cubic interpolation spline curve
class CSpline 
{

public:
	double* Px;
	double* Py;
	double* Ax;
	double* Ay;
	double* Bx;
	double* By;
	double* Cx;
	double* Cy;
	double* k;
	double* Mat[3];
	std::vector<Vector2> Normal;
	int  NP;

	// constructor
	CSpline(POINT pt[], int np);
	CSpline(double px[] , double py[] , int np);
	CSpline( CPolygon *pPoly );
	~CSpline();
	void	SetSize( int np );
	void	Clear();
	void	Init();
	void	Generate();
	void	MatrixSolve(double B[]);
	int		NumPoints();
	void	GetPoints( std::vector<CVertex> &verts, bool closed );
	void	Draw( CDC *pDC );
	void	DrawInGL( CSize window_size, float fGLViewWidth, float fGLViewHeight,
					CPseudoColorRGB &PsdC,Vector2 Origin/*=Vector2(0,0)*/,
					bool bDrawCurve/*=true*/, bool bDrawVertex/*=true*/);
	//////////// closed cubic spline ////////////////////
	void	GenClosed();
	///// tridiagonal matrix + elements of [0][0], [N-1][N-1] //// 
	void	MatrixSolveEX(double B[]);
	void	DrawClosed( CDC *pDC );
	void	VertexNormal();
	void	DrawNormal(CDC *pDC);	
};

#endif	// _SPLINE_H_
